﻿Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.IO
Imports System.Windows.Forms
Imports System.Workflow.ComponentModel

Namespace System.Workflow.ComponentModel.Design
    Friend Class DragDropManager
        Inherits WorkflowDesignerMessageFilter
        ' Methods
        Friend Sub New()
        End Sub

        Private Function CanInitiateDragDrop() As Boolean
            Dim service As ISelectionService = DirectCast(MyBase.GetService(GetType(ISelectionService)), ISelectionService)
            Dim host As IDesignerHost = DirectCast(MyBase.GetService(GetType(IDesignerHost)), IDesignerHost)
            If ((service Is Nothing) OrElse (host Is Nothing)) Then
                Return False
            End If
            Dim selectedComponents As ICollection = service.GetSelectedComponents
            Return (((Not selectedComponents Is Nothing) AndAlso (selectedComponents.Count >= 1)) AndAlso (Not service.GetComponentSelected(host.RootComponent) AndAlso Helpers.AreAllActivities(selectedComponents)))
        End Function

        Protected Overridable Sub CreateDragFeedbackImages(ByVal draggedActivities As IList([Of] Activity))
            Dim image As Bitmap = Nothing
            If (draggedActivities.Count > 0) Then
                Dim bitmap2 As Bitmap = Nothing
                Dim s As String = String.Empty
                If (draggedActivities.Count > 1) Then
                    bitmap2 = [TryCast](DR.GetImage("Activities"),Bitmap)
                    s = DR.GetString("ActivitiesDesc", New Object(0  - 1) {})
                Else
                    Dim attribute As ToolboxBitmapAttribute = DirectCast(TypeDescriptor.GetAttributes(draggedActivities.Item(0).GetType).Item(GetType(ToolboxBitmapAttribute)), ToolboxBitmapAttribute)
                    bitmap2 = [TryCast](attribute.GetImage(draggedActivities.Item(0).GetType),Bitmap)
                    s = draggedActivities.Item(0).GetType.Name
                End If
                If ((Not bitmap2 Is Nothing) AndAlso (s.Length > 0)) Then
                    Dim parentView As WorkflowView = MyBase.ParentView
                    Dim rectangle As Rectangle = If((Not bitmap2 Is Nothing), New Rectangle(Point.Empty, bitmap2.Size), Rectangle.Empty)
                    Dim layoutRectangle As Rectangle = If((s.Length > 0), New Rectangle(Point.Empty, New Size(AmbientTheme.DragImageTextSize.Width, (parentView.Font.Height + 2))), Rectangle.Empty)
                    If Not rectangle.IsEmpty Then
                        layoutRectangle.Offset((rectangle.Width + AmbientTheme.DragImageMargins.Width), 0)
                    End If
                    Dim size As Size = parentView.LogicalSizeToClient(New Size((rectangle.Width + layoutRectangle.Width), Math.Max(rectangle.Height, layoutRectangle.Height)))
                    image = New Bitmap(size.Width, size.Height, PixelFormat.Format32bppArgb)
                    [Using] graphics As Graphics = Graphics.FromImage(image)
                        [Using] brush As Brush = New SolidBrush(Color.FromArgb(0, &HFF, 0, &HFF))
                            graphics.ScaleTransform(Me.ScaleZoomFactor, Me.ScaleZoomFactor)
                            graphics.FillRectangle(brush, New Rectangle(0, 0, image.Width, image.Height))
                            If (Not bitmap2 Is Nothing) Then
                                graphics.DrawImage(bitmap2, New Rectangle(Point.Empty, bitmap2.Size))
                            End If
                            If (s.Length > 0) Then
                                Dim format As New StringFormat { _
                                    .Alignment = StringAlignment.Near, _
                                    .Trimming = StringTrimming.EllipsisCharacter, _
                                    .LineAlignment = StringAlignment.Center _
                                }
                                graphics.DrawString(s, parentView.Font, SystemBrushes.WindowText, layoutRectangle, format)
                            End If
                        End [Using]
                    End [Using]
                End If
            End If
            Me.dragImage = image
        End Sub

        Protected Overridable Sub DestroyDragFeedbackImages()
            If (Not Me.dragImage Is Nothing) Then
                Me.dragImage.Dispose
                Me.dragImage = Nothing
            End If
        End Sub

        Protected Overrides Sub Dispose(ByVal disposing As Boolean)
            Try 
                If disposing Then
                    Dim service As IServiceContainer = [TryCast](MyBase.GetService(GetType(IServiceContainer)),IServiceContainer)
                    If (Not service Is Nothing) Then
                        service.RemoveService(GetType(DragDropManager))
                    End If
                End If
            Finally
                MyBase.Dispose(disposing)
            End Try
        End Sub

        Protected Overrides Sub Initialize(ByVal parentView As WorkflowView)
            MyBase.Initialize(parentView)
            Dim service As IServiceContainer = [TryCast](MyBase.GetService(GetType(IServiceContainer)),IServiceContainer)
            If (Not service Is Nothing) Then
                service.RemoveService(GetType(DragDropManager))
                service.AddService(GetType(DragDropManager), Me)
            End If
        End Sub

        Private Sub InitiateDragDrop()
            Dim parentView As WorkflowView = MyBase.ParentView
            Dim service As ISelectionService = DirectCast(MyBase.GetService(GetType(ISelectionService)), ISelectionService)
            Dim host As IDesignerHost = DirectCast(MyBase.GetService(GetType(IDesignerHost)), IDesignerHost)
            If ((Not service Is Nothing) AndAlso (Not host Is Nothing)) Then
                Dim selectedComponents As ICollection = service.GetSelectedComponents
                If (((Not selectedComponents Is Nothing) AndAlso (selectedComponents.Count >= 1)) AndAlso (Not service.GetComponentSelected(host.RootComponent) AndAlso Helpers.AreAllActivities(selectedComponents))) Then
                    Dim none As DragDropEffects = DragDropEffects.None
                    Try 
                        Me.existingDraggedActivities.AddRange(Helpers.GetTopLevelActivities(selectedComponents))
                        Dim allowedEffects As DragDropEffects = If(DesignerHelpers.AreAssociatedDesignersMovable(Me.existingDraggedActivities), (DragDropEffects.Move Or DragDropEffects.Copy), DragDropEffects.Copy)
                        Dim data As IDataObject = CompositeActivityDesigner.SerializeActivitiesToDataObject(MyBase.ParentView, Me.existingDraggedActivities.ToArray)
                        none = parentView.DoDragDrop(data, allowedEffects)
                    Catch exception As Exception
                        DesignerHelpers.ShowError(MyBase.ParentView, exception.Message)
                    Finally
                        If ((none = DragDropEffects.Move) AndAlso (Me.existingDraggedActivities.Count > 0)) Then
                            Dim transactionDescription As String = String.Empty
                            If (Me.existingDraggedActivities.Count > 1) Then
                                transactionDescription = SR.GetString("MoveMultipleActivities", New Object() { Me.existingDraggedActivities.Count })
                            Else
                                transactionDescription = SR.GetString("MoveSingleActivity", New Object() { Me.existingDraggedActivities.Item(0).GetType })
                            End If
                            CompositeActivityDesigner.RemoveActivities(MyBase.ParentView, Me.existingDraggedActivities.AsReadOnly, transactionDescription)
                        End If
                        Me.existingDraggedActivities.Clear
                    End Try
                End If
            End If
        End Sub

        Private Function IsRecursiveDropOperation(ByVal dropTargetDesigner As ActivityDesigner) As Boolean
            If (Not dropTargetDesigner Is Nothing) Then
                Dim service As ISelectionService = DirectCast(MyBase.GetService(GetType(ISelectionService)), ISelectionService)
                Dim activity As CompositeActivity = [TryCast](dropTargetDesigner.Activity,CompositeActivity)
                If ((activity Is Nothing) OrElse (service Is Nothing)) Then
                    Return False
                End If
                MyBase.GetService(GetType(WorkflowView))
                MyBase.GetService(GetType(IDesignerHost))
                MyBase.GetService(GetType(WorkflowDesignerLoader))
                If ((Me.draggedActivities.Count = 0) OrElse (Me.existingDraggedActivities.Count = 0)) Then
                    Return False
                End If
                Dim list As New ArrayList(Helpers.GetTopLevelActivities(service.GetSelectedComponents))
                Dim activity2 As CompositeActivity = activity
                Do While (Not activity2 Is Nothing)
                    If list.Contains(activity2) Then
                        Return True
                    End If
                    activity2 = activity2.Parent
                Loop
            End If
            Return False
        End Function

        Friend Function IsValidDropContext(ByVal dropLocation As HitTestInfo) As Boolean
            If (Me.draggedActivities.Count = 0) Then
                Return False
            End If
            If ((dropLocation Is Nothing) OrElse (dropLocation.AssociatedDesigner Is Nothing)) Then
                Return False
            End If
            Dim associatedDesigner As CompositeActivityDesigner = [TryCast](dropLocation.AssociatedDesigner,CompositeActivityDesigner)
            If (associatedDesigner Is Nothing) Then
                Return False
            End If
            If (Not associatedDesigner.IsEditable OrElse Not associatedDesigner.CanInsertActivities(dropLocation, New List([Of] Activity)(Me.draggedActivities).AsReadOnly)) Then
                Return False
            End If
            If (Not Me.wasCtrlKeyPressed AndAlso (Me.existingDraggedActivities.Count > 0)) Then
                If Not DesignerHelpers.AreAssociatedDesignersMovable(Me.draggedActivities) Then
                    Return False
                End If
                If Me.IsRecursiveDropOperation(dropLocation.AssociatedDesigner) Then
                    Return False
                End If
                Dim entry As DictionaryEntry
                For Each entry In Helpers.PairUpCommonParentActivities(Me.draggedActivities)
                    Dim designer As CompositeActivityDesigner = [TryCast](ActivityDesigner.GetDesigner([TryCast](entry.Key,Activity)),CompositeActivityDesigner)
                    Dim collection As Activity() = DirectCast(DirectCast(entry.Value, ArrayList).ToArray(GetType(Activity)), Activity())
                    If ((Not designer Is Nothing) AndAlso Not designer.CanMoveActivities(dropLocation, New List([Of] Activity)(collection).AsReadOnly)) Then
                        Return False
                    End If
                Next
            End If
            Return True
        End Function

        Protected Overrides Function OnDragDrop(ByVal eventArgs As DragEventArgs) As Boolean
            Dim parentView As WorkflowView = MyBase.ParentView
            parentView.InvalidateClientRectangle(Rectangle.Empty)
            eventArgs.Effect = DragDropEffects.None
            Me.DestroyDragFeedbackImages
            Dim clientPoint As Point = parentView.PointToClient(New Point(eventArgs.X, eventArgs.Y))
            Dim point As Point = parentView.ScreenPointToLogical(New Point(eventArgs.X, eventArgs.Y))
            If Not parentView.IsClientPointInActiveLayout(clientPoint) Then
                If (Not Me.dropTargetDesigner Is Nothing) Then
                    DirectCast(Me.dropTargetDesigner, IWorkflowDesignerMessageSink).OnDragLeave
                End If
                Me.wasCtrlKeyPressed = False
                Me.dropTargetDesigner = Nothing
                Me.draggedActivities.Clear
                Return False
            End If
            Me.wasCtrlKeyPressed = ((eventArgs.KeyState And 8) = 8)
            Dim e As New ActivityDragEventArgs(eventArgs, Me.dragInitiationPoint, point, Me.draggedActivities)
            Dim messageHitTestContext As HitTestInfo = MyBase.MessageHitTestContext
            If (Not Me.dropTargetDesigner Is messageHitTestContext.AssociatedDesigner) Then
                If (Not Me.dropTargetDesigner Is Nothing) Then
                    DirectCast(Me.dropTargetDesigner, IWorkflowDesignerMessageSink).OnDragLeave
                    Me.dropTargetDesigner = Nothing
                End If
                If (Not messageHitTestContext.AssociatedDesigner Is Nothing) Then
                    Me.dropTargetDesigner = messageHitTestContext.AssociatedDesigner
                    If (Not Me.dropTargetDesigner Is Nothing) Then
                        DirectCast(Me.dropTargetDesigner, IWorkflowDesignerMessageSink).OnDragEnter(e)
                    End If
                End If
            End If
            Try 
                If (Not Me.dropTargetDesigner Is Nothing) Then
                    If ((Not Me.wasCtrlKeyPressed AndAlso Me.IsRecursiveDropOperation(Me.dropTargetDesigner)) OrElse (TypeOf Me.dropTargetDesigner Is CompositeActivityDesigner AndAlso Not DirectCast(Me.dropTargetDesigner, CompositeActivityDesigner).IsEditable)) Then
                        DirectCast(Me.dropTargetDesigner, IWorkflowDesignerMessageSink).OnDragLeave
                        e.Effect = DragDropEffects.None
                    Else
                        Dim draggedActivities As New List([Of] Activity)
                        Dim description As String = SR.GetString("DragDropActivities")
                        If (Not Me.wasCtrlKeyPressed AndAlso (Me.existingDraggedActivities.Count > 0)) Then
                            draggedActivities.AddRange(Me.existingDraggedActivities)
                            If (draggedActivities.Count > 1) Then
                                description = SR.GetString("MoveMultipleActivities", New Object() { draggedActivities.Count })
                            ElseIf (draggedActivities.Count = 1) Then
                                description = SR.GetString("MoveSingleActivity", New Object() { draggedActivities.Item(0).GetType })
                            End If
                        Else
                            draggedActivities.AddRange(CompositeActivityDesigner.DeserializeActivitiesFromDataObject(MyBase.ParentView, eventArgs.Data, True))
                            If (draggedActivities.Count > 0) Then
                                description = SR.GetString("CreateActivityFromToolbox", New Object() { draggedActivities.Item(0).GetType })
                            End If
                        End If
                        Dim host As IDesignerHost = [TryCast](MyBase.GetService(GetType(IDesignerHost)),IDesignerHost)
                        Dim transaction As DesignerTransaction = Nothing
                        If (draggedActivities.Count > 0) Then
                            transaction = host.CreateTransaction(description)
                        End If
                        e = New ActivityDragEventArgs(eventArgs, Me.dragInitiationPoint, point, draggedActivities)
                        Try 
                            DirectCast(Me.dropTargetDesigner, IWorkflowDesignerMessageSink).OnDragDrop(e)
                            If (e.Effect = DragDropEffects.Move) Then
                                Me.existingDraggedActivities.Clear
                            End If
                            If (Not transaction Is Nothing) Then
                                transaction.Commit
                            End If
                        Catch exception As Exception
                            If (Not transaction Is Nothing) Then
                                transaction.Cancel
                            End If
                            Throw exception
                        End Try
                        If (draggedActivities.Count > 0) Then
                            Dim data As Stream = [TryCast](eventArgs.Data.GetData("CF_WINOEDESIGNERCOMPONENTSSTATE"),Stream)
                            If (Not data Is Nothing) Then
                                Helpers.DeserializeDesignersFromStream(draggedActivities, data)
                            End If
                            Dim service As ISelectionService = DirectCast(MyBase.GetService(GetType(ISelectionService)), ISelectionService)
                            If (Not service Is Nothing) Then
                                service.SetSelectedComponents(draggedActivities, SelectionTypes.Replace)
                            End If
                        End If
                        If (Not host Is Nothing) Then
                            host.Activate
                        End If
                    End If
                End If
            Catch exception2 As Exception
                DirectCast(Me.dropTargetDesigner, IWorkflowDesignerMessageSink).OnDragLeave
                e.Effect = DragDropEffects.None
                Dim message As String = exception2.Message
                If ((Not exception2.InnerException Is Nothing) AndAlso Not String.IsNullOrEmpty(exception2.InnerException.Message)) Then
                    message = exception2.InnerException.Message
                End If
                Dim str3 As String = (DR.GetString("Error_FailedToDeserializeComponents", New Object(0  - 1) {}) & ChrW(13) & ChrW(10) & DR.GetString("Error_Reason", New Object() { message }))
                DesignerHelpers.ShowError(MyBase.ParentView, str3)
                If (Not exception2 Is CheckoutException.Canceled) Then
                    Throw New Exception(str3, exception2)
                End If
            Finally
                Me.wasCtrlKeyPressed = False
                Me.draggedActivities.Clear
                Me.dropTargetDesigner = Nothing
                Me.exceptionInDragDrop = False
                eventArgs.Effect = e.Effect
            End Try
            Return True
        End Function

        Protected Overrides Function OnDragEnter(ByVal eventArgs As DragEventArgs) As Boolean
            Dim parentView As WorkflowView = MyBase.ParentView
            parentView.InvalidateClientRectangle(Rectangle.Empty)
            eventArgs.Effect = DragDropEffects.None
            Me.wasCtrlKeyPressed = False
            If (Me.existingDraggedActivities.Count > 0) Then
                Me.draggedActivities.AddRange(Me.existingDraggedActivities)
            Else
                Try 
                    Dim collection As Activity() = CompositeActivityDesigner.DeserializeActivitiesFromDataObject(MyBase.ParentView, eventArgs.Data)
                    If (Not collection Is Nothing) Then
                        Me.draggedActivities.AddRange(collection)
                    End If
                Catch obj1 As Object
                    Me.exceptionInDragDrop = True
                End Try
            End If
            Dim clientPoint As Point = parentView.PointToClient(New Point(eventArgs.X, eventArgs.Y))
            Dim point As Point = parentView.ScreenPointToLogical(New Point(eventArgs.X, eventArgs.Y))
            Me.CreateDragFeedbackImages(Me.draggedActivities)
            If (Not Me.dragImage Is Nothing) Then
                Me.dragImagePointInClientCoOrd = New Point((clientPoint.X + (SystemInformation.CursorSize.Width / 4)), (clientPoint.Y + (SystemInformation.CursorSize.Height / 4)))
            End If
            If Not parentView.IsClientPointInActiveLayout(clientPoint) Then
                Return False
            End If
            Me.wasCtrlKeyPressed = ((eventArgs.KeyState And 8) = 8)
            Dim e As New ActivityDragEventArgs(eventArgs, Me.dragInitiationPoint, point, Me.draggedActivities)
            Dim associatedDesigner As ActivityDesigner = MyBase.MessageHitTestContext.AssociatedDesigner
            If (associatedDesigner Is Nothing) Then
                Return False
            End If
            If (Not Me.wasCtrlKeyPressed AndAlso Me.IsRecursiveDropOperation(associatedDesigner)) Then
                Return False
            End If
            Dim designer2 As CompositeActivityDesigner = [TryCast](associatedDesigner,CompositeActivityDesigner)
            If ((Not designer2 Is Nothing) AndAlso Not designer2.IsEditable) Then
                Return False
            End If
            Me.dropTargetDesigner = associatedDesigner
            DirectCast(Me.dropTargetDesigner, IWorkflowDesignerMessageSink).OnDragEnter(e)
            If Not e.DragImageSnapPoint.IsEmpty Then
                Dim point3 As Point = parentView.LogicalPointToClient(e.DragImageSnapPoint)
                Dim size As Size = parentView.LogicalSizeToClient(AmbientTheme.DragImageIconSize)
                Me.dragImagePointInClientCoOrd = New Point((point3.X - (size.Width / 2)), (point3.Y - (size.Height / 2)))
                Me.dragImageSnapped = True
            End If
            eventArgs.Effect = e.Effect
            If ((eventArgs.Effect = DragDropEffects.None) AndAlso Me.exceptionInDragDrop) Then
                eventArgs.Effect = If(Me.wasCtrlKeyPressed, DragDropEffects.Copy, DragDropEffects.Move)
            End If
            Return True
        End Function

        Protected Overrides Function OnDragLeave() As Boolean
            MyBase.ParentView.InvalidateClientRectangle(Rectangle.Empty)
            Me.DestroyDragFeedbackImages
            Me.wasCtrlKeyPressed = False
            If (Not Me.dropTargetDesigner Is Nothing) Then
                DirectCast(Me.dropTargetDesigner, IWorkflowDesignerMessageSink).OnDragLeave
            End If
            Me.dropTargetDesigner = Nothing
            Me.draggedActivities.Clear
            Me.exceptionInDragDrop = False
            Return True
        End Function

        Protected Overrides Function OnDragOver(ByVal eventArgs As DragEventArgs) As Boolean
            eventArgs.Effect = DragDropEffects.None
            Me.wasCtrlKeyPressed = False
            Me.dragImageSnapped = False
            Dim parentView As WorkflowView = MyBase.ParentView
            Dim clientPoint As Point = parentView.PointToClient(New Point(eventArgs.X, eventArgs.Y))
            Dim point As Point = parentView.ScreenPointToLogical(New Point(eventArgs.X, eventArgs.Y))
            Dim dragImagePointInClientCoOrd As Point = Me.dragImagePointInClientCoOrd
            Me.dragImagePointInClientCoOrd = New Point((clientPoint.X + (SystemInformation.CursorSize.Width / 4)), (clientPoint.Y + (SystemInformation.CursorSize.Height / 4)))
            If Not parentView.IsClientPointInActiveLayout(clientPoint) Then
                If (Not Me.dropTargetDesigner Is Nothing) Then
                    DirectCast(Me.dropTargetDesigner, IWorkflowDesignerMessageSink).OnDragLeave
                End If
                Me.dropTargetDesigner = Nothing
            Else
                Me.wasCtrlKeyPressed = ((eventArgs.KeyState And 8) = 8)
                Dim e As New ActivityDragEventArgs(eventArgs, Me.dragInitiationPoint, point, Me.draggedActivities)
                Dim associatedDesigner As ActivityDesigner = MyBase.MessageHitTestContext.AssociatedDesigner
                If (Not associatedDesigner Is Nothing) Then
                    Dim designer2 As CompositeActivityDesigner = [TryCast](associatedDesigner,CompositeActivityDesigner)
                    If ((Not Me.wasCtrlKeyPressed AndAlso Me.IsRecursiveDropOperation(associatedDesigner)) OrElse ((Not designer2 Is Nothing) AndAlso Not designer2.IsEditable)) Then
                        e.Effect = DragDropEffects.None
                        associatedDesigner = Nothing
                    End If
                End If
                If (Not Me.dropTargetDesigner Is associatedDesigner) Then
                    If (Not Me.dropTargetDesigner Is Nothing) Then
                        DirectCast(Me.dropTargetDesigner, IWorkflowDesignerMessageSink).OnDragLeave
                    End If
                    Me.dropTargetDesigner = associatedDesigner
                    If (Not Me.dropTargetDesigner Is Nothing) Then
                        DirectCast(Me.dropTargetDesigner, IWorkflowDesignerMessageSink).OnDragEnter(e)
                    End If
                Else
                    If (Not Me.dropTargetDesigner Is Nothing) Then
                        DirectCast(Me.dropTargetDesigner, IWorkflowDesignerMessageSink).OnDragOver(e)
                    End If
                    If ((e.Effect <> DragDropEffects.None) AndAlso Not e.DragImageSnapPoint.IsEmpty) Then
                        Dim point4 As Point = parentView.LogicalPointToClient(e.DragImageSnapPoint)
                        Dim size As Size = parentView.LogicalSizeToClient(AmbientTheme.DragImageIconSize)
                        Me.dragImagePointInClientCoOrd = New Point((point4.X - (size.Width / 2)), (point4.Y - (size.Height / 2)))
                        Me.dragImageSnapped = True
                    End If
                End If
                eventArgs.Effect = e.Effect
            End If
            If (Not Me.dragImage Is Nothing) Then
                parentView.InvalidateClientRectangle(New Rectangle(dragImagePointInClientCoOrd, Me.dragImage.Size))
                parentView.InvalidateClientRectangle(New Rectangle(Me.dragImagePointInClientCoOrd, Me.dragImage.Size))
            End If
            If ((eventArgs.Effect = DragDropEffects.None) AndAlso Me.exceptionInDragDrop) Then
                eventArgs.Effect = If(Me.wasCtrlKeyPressed, DragDropEffects.Copy, DragDropEffects.Move)
            End If
            Return True
        End Function

        Protected Overrides Function OnGiveFeedback(ByVal gfbevent As GiveFeedbackEventArgs) As Boolean
            If (Not Me.dropTargetDesigner Is Nothing) Then
                DirectCast(Me.dropTargetDesigner, IWorkflowDesignerMessageSink).OnGiveFeedback(gfbevent)
            End If
            Return True
        End Function

        Protected Overrides Function OnKeyDown(ByVal eventArgs As KeyEventArgs) As Boolean
            If (Me.draggedDesigner Is Nothing) Then
                Return False
            End If
            If (eventArgs.KeyValue = &H1B) Then
                DirectCast(Me.draggedDesigner, IWorkflowDesignerMessageSink).OnMouseDragEnd
                Me.draggedDesigner = Nothing
                Me.dragStarted = False
                MyBase.ParentView.Capture = False
            Else
                DirectCast(Me.draggedDesigner, IWorkflowDesignerMessageSink).OnKeyDown(eventArgs)
                eventArgs.Handled = True
            End If
            Return True
        End Function

        Protected Overrides Function OnKeyUp(ByVal eventArgs As KeyEventArgs) As Boolean
            If (Not Me.draggedDesigner Is Nothing) Then
                DirectCast(Me.draggedDesigner, IWorkflowDesignerMessageSink).OnKeyUp(eventArgs)
                eventArgs.Handled = True
                Return True
            End If
            Return False
        End Function

        Protected Overrides Function OnMouseCaptureChanged() As Boolean
            If Not MyBase.ParentView.Capture Then
                If (Not Me.draggedDesigner Is Nothing) Then
                    DirectCast(Me.draggedDesigner, IWorkflowDesignerMessageSink).OnMouseDragEnd
                End If
                Me.draggedDesigner = Nothing
                Me.dragStarted = False
            End If
            Return False
        End Function

        Protected Overrides Function OnMouseDown(ByVal eventArgs As MouseEventArgs) As Boolean
            Dim parentView As WorkflowView = MyBase.ParentView
            Dim clientPoint As New Point(eventArgs.X, eventArgs.Y)
            If (parentView.IsClientPointInActiveLayout(clientPoint) AndAlso (eventArgs.Button = MouseButtons.Left)) Then
                Me.dragInitiationPoint = parentView.ClientPointToLogical(clientPoint)
                Me.dragStarted = True
            End If
            Return False
        End Function

        Protected Overrides Function OnMouseEnter(ByVal eventArgs As MouseEventArgs) As Boolean
            Return (Not Me.draggedDesigner Is Nothing)
        End Function

        Protected Overrides Function OnMouseHover(ByVal eventArgs As MouseEventArgs) As Boolean
            Return (Not Me.draggedDesigner Is Nothing)
        End Function

        Protected Overrides Function OnMouseLeave() As Boolean
            Return (Not Me.draggedDesigner Is Nothing)
        End Function

        Protected Overrides Function OnMouseMove(ByVal eventArgs As MouseEventArgs) As Boolean
            Dim parentView As WorkflowView = MyBase.ParentView
            Dim clientPoint As New Point(eventArgs.X, eventArgs.Y)
            If Not parentView.IsClientPointInActiveLayout(clientPoint) Then
                Return False
            End If
            If (eventArgs.Button = MouseButtons.Left) Then
                Dim point2 As Point = parentView.ClientPointToLogical(clientPoint)
                Dim messageHitTestContext As HitTestInfo = MyBase.MessageHitTestContext
                If (Not Me.draggedDesigner Is Nothing) Then
                    DirectCast(Me.draggedDesigner, IWorkflowDesignerMessageSink).OnMouseDragMove(eventArgs)
                ElseIf ((((Not parentView.RootDesigner Is Nothing) AndAlso Me.dragStarted) AndAlso ((eventArgs.Button And MouseButtons.Left) > MouseButtons.None)) AndAlso ((Math.Abs(CInt((Me.dragInitiationPoint.X - point2.X))) > SystemInformation.DragSize.Width) OrElse (Math.Abs(CInt((Me.dragInitiationPoint.Y - point2.Y))) > SystemInformation.DragSize.Height))) Then
                    Dim associatedDesigner As ActivityDesigner = messageHitTestContext.AssociatedDesigner
                    If (Not associatedDesigner Is Nothing) Then
                        If Me.CanInitiateDragDrop Then
                            Me.InitiateDragDrop
                            Me.dragStarted = False
                        Else
                            Me.draggedDesigner = associatedDesigner
                            DirectCast(Me.draggedDesigner, IWorkflowDesignerMessageSink).OnMouseDragBegin(Me.dragInitiationPoint, eventArgs)
                            parentView.Capture = True
                        End If
                    End If
                End If
            Else
                If (Not Me.draggedDesigner Is Nothing) Then
                    DirectCast(Me.draggedDesigner, IWorkflowDesignerMessageSink).OnMouseDragEnd
                End If
                Me.draggedDesigner = Nothing
            End If
            Return (Not Me.draggedDesigner Is Nothing)
        End Function

        Protected Overrides Function OnMouseUp(ByVal eventArgs As MouseEventArgs) As Boolean
            If (Not Me.draggedDesigner Is Nothing) Then
                DirectCast(Me.draggedDesigner, IWorkflowDesignerMessageSink).OnMouseDragEnd
                Me.draggedDesigner = Nothing
                Me.dragStarted = False
                MyBase.ParentView.Capture = False
                Return True
            End If
            Return False
        End Function

        Protected Overrides Function OnPaintWorkflowAdornments(ByVal e As PaintEventArgs, ByVal viewPort As Rectangle, ByVal ambientTheme As AmbientTheme) As Boolean
            If (Not Me.dragImage Is Nothing) Then
                ActivityDesignerPaint.DrawImage(e.Graphics, Me.dragImage, New Rectangle(Me.dragImagePointInClientCoOrd, Me.dragImage.Size), New Rectangle(0, 0, Me.dragImage.Width, Me.dragImage.Height), DesignerContentAlignment.Center, If(Me.dragImageSnapped, 1!, 0.5!), WorkflowTheme.CurrentTheme.AmbientTheme.DrawGrayscale)
            End If
            Return False
        End Function

        Protected Overrides Function OnQueryContinueDrag(ByVal qcdevent As QueryContinueDragEventArgs) As Boolean
            If (Not Me.dropTargetDesigner Is Nothing) Then
                DirectCast(Me.dropTargetDesigner, IWorkflowDesignerMessageSink).OnQueryContinueDrag(qcdevent)
            End If
            Return True
        End Function


        ' Properties
        Public ReadOnly Property DraggedActivities As IList([Of] Activity)
            Get
                Return Me.draggedActivities.AsReadOnly
            End Get
        End Property

        Public ReadOnly Property DraggedDesigner As ActivityDesigner
            Get
                Return Me.draggedDesigner
            End Get
        End Property

        Public ReadOnly Property DragInitiationPoint As Point
            Get
                Return Me.dragInitiationPoint
            End Get
        End Property

        Public ReadOnly Property DropTargetDesigner As ActivityDesigner
            Get
                Return Me.dropTargetDesigner
            End Get
        End Property

        Private ReadOnly Property ScaleZoomFactor As Single
            Get
                Dim parentView As WorkflowView = MyBase.ParentView
                Return ((CSng(parentView.Zoom) / 100!) * parentView.ActiveLayout.Scaling)
            End Get
        End Property


        ' Fields
        Private Const CF_DESIGNERSTATE As String = "CF_WINOEDESIGNERCOMPONENTSSTATE"
        Private draggedActivities As List([Of] Activity) = New List([Of] Activity)
        Private draggedDesigner As ActivityDesigner
        Private dragImage As Image
        Private dragImagePointInClientCoOrd As Point = Point.Empty
        Private dragImageSnapped As Boolean
        Private dragInitiationPoint As Point = Point.Empty
        Private dragStarted As Boolean
        Private dropTargetDesigner As ActivityDesigner
        Private exceptionInDragDrop As Boolean
        Private existingDraggedActivities As List([Of] Activity) = New List([Of] Activity)
        Private wasCtrlKeyPressed As Boolean
    End Class
End Namespace

